) where
import Utility.FileSystemEncoding
-
+import Data.ByteString.Short (ShortByteString)
+import qualified Data.ByteString.Short as S
#ifdef WITH_OSPATH
+import System.OsPath as X hiding (OsPath, OsString, unsafeFromChar)
import System.OsPath
import "os-string" System.OsString.Internal.Types
-import qualified Data.ByteString.Short as S
+import qualified System.FilePath.ByteString as PB
+ #if defined(mingw32_HOST_OS)
+ import GHC.IO (unsafePerformIO)
+ import System.OsString.Encoding.Internal (cWcharsToChars_UCS2)
+ import qualified System.OsString.Data.ByteString.Short.Word16 as BS16
+ #endif
+#else
+import System.FilePath.ByteString as X hiding (RawFilePath, getSearchPath)
+import System.FilePath.ByteString (getSearchPath)
+import Data.ByteString (ByteString)
+import Data.Char
+import Data.Word
+#endif
+
+class OsPathConv t where
+ toOsPath :: t -> OsPath
+ fromOsPath :: OsPath -> t
+
+instance OsPathConv FilePath where
+ toOsPath = toOsPath . toRawFilePath
+ fromOsPath = fromRawFilePath . fromOsPath
+
+#ifdef WITH_OSPATH
+instance OsPathConv RawFilePath where
+ toOsPath = bytesToOsPath . S.toShort
++#if defined(mingw32_HOST_OS)
++ fromOsPath = bytesFromOsPath
++#else
+ fromOsPath = S.fromShort . bytesFromOsPath
++#endif
+
+instance OsPathConv ShortByteString where
+ toOsPath = bytesToOsPath
++#if defined(mingw32_HOST_OS)
++ fromOsPath = S.toShort . bytesFromOsPath
++#else
+ fromOsPath = bytesFromOsPath
++#endif
- {- Unlike System.OsString.fromBytes, on Windows this does not ensure a
- - valid USC-2LE encoding. The input ByteString must be in a valid encoding
- - already or uses of the OsPath will fail. -}
-toOsPath :: RawFilePath -> OsPath
+bytesToOsPath :: ShortByteString -> OsPath
#if defined(mingw32_HOST_OS)
- bytesToOsPath = OsString . WindowsString
+ -- On Windows, OsString contains a ShortByteString that is
+ -- utf-16 encoded. So have to convert the input to that.
+ -- This is relatively expensive.
-toOsPath = unsafePerformIO . encodeFS . fromRawFilePath
++bytesToOsPath = unsafePerformIO . encodeFS . fromRawFilePath
#else
-toOsPath = OsString . PosixString . S.toShort
+bytesToOsPath = OsString . PosixString
#endif
- bytesFromOsPath :: OsPath -> ShortByteString
-fromOsPath :: OsPath -> RawFilePath
#if defined(mingw32_HOST_OS)
- bytesFromOsPath = getWindowsString . getOsString
++bytesFromOsPath :: OsPath -> RawFilePath
+ -- On Windows, OsString contains a ShortByteString that is
+ -- utf-16 encoded. So have to convert the input from that.
+ -- This is relatively expensive.
-fromOsPath = toRawFilePath . cWcharsToChars_UCS2 . BS16.unpack . getWindowsString
++bytesFromOsPath = toRawFilePath . cWcharsToChars_UCS2 . BS16.unpack . getWindowsString
#else
-fromOsPath = S.fromShort . getPosixString . getOsString
++bytesFromOsPath :: OsPath -> ShortByteString
+bytesFromOsPath = getPosixString . getOsString
#endif
+{- For some reason not included in System.OsPath -}
+getSearchPath :: IO [OsPath]
+getSearchPath = map toOsPath <$> PB.getSearchPath
+
+{- Used for string constants. -}
+literalOsPath :: ShortByteString -> OsPath
+literalOsPath = bytesToOsPath
+
#else
-{- When not building with WITH_OSPATH, use FilePath. This allows
- - using functions from legacy FilePath libraries interchangeably with
- - newer OsPath libraries.
+{- When not building with WITH_OSPATH, use RawFilePath.
-}
-type OsPath = FilePath
+type OsPath = RawFilePath
+
+type OsString = ByteString
+
+instance OsPathConv RawFilePath where
+ toOsPath = id
+ fromOsPath = id
-type OsString = String
+instance OsPathConv ShortByteString where
+ toOsPath = S.fromShort
+ fromOsPath = S.toShort
-toOsPath :: RawFilePath -> OsPath
-toOsPath = fromRawFilePath
+unsafeFromChar :: Char -> Word8
+unsafeFromChar = fromIntegral . ord
-fromOsPath :: OsPath -> RawFilePath
-fromOsPath = toRawFilePath
+literalOsPath :: RawFilePath -> OsPath
+literalOsPath = id
#endif